Complete Rust programming Guide for Beginners

rust programming language wallpaper

Rust is a modern systems programming language designed for speed, safety, concurrency, and portability, making it a favorite among developers worldwide. Created by Graydon Hoare in 2007 and sponsored by Mozilla, Rust’s first stable release was in 2014. It shares similarities with C and C++ but introduces innovative concepts like ownership to ensure memory safety without a garbage collector.

According to the Stack Overflow Developer Survey, Rust has been the most admired programming language for seven consecutive years, with more than 80% of developers expressing a desire to continue using it. Major tech companies such as Dropbox, Discord, Amazon, Facebook, Microsoft, and Mozilla rely on Rust for building reliable and efficient software.

Why Choose Rust as a programming language?

Rust strikes a unique balance between:

  • Speed: Comparable to C and C++ due to its compiled nature.
  • Safety: Guarantees memory safety via ownership rules, preventing bugs common in C/C++.
  • Concurrency: Supports safe multi-threaded programming without data races.
  • Portability: Rust programs can be compiled once and run across Windows, Linux, and macOS.

Notably, the White House has recommended transitioning from C and C++ to Rust to enhance cybersecurity through memory-safe programming.

Getting Started with Rust

Installing Rust

Visit rust-lang.org to download and install Rust easily via rustup, the official Rust installer and version manager. You can install Rust on Windows, Linux, or macOS using simple commands or executables.

After installation, verify by running:

rustc --version
cargo --version

These commands check the Rust compiler and Cargo package manager versions.

Writing Your First Rust Program

Create a Rust file named hello.rs:

fn main() {
    println!("Hello, world!");
}

Compile and run it using:

rustc hello.rs
./hello

Alternatively, use Cargo, Rust’s package manager and build tool:

cargo new hello_project
cd hello_project
cargo run

Cargo automatically handles compilation and running, streamlining development.

Core Concepts in Rust Programming

Primitive Data Types

Rust is a statically typed language, requiring explicit or inferred data types for variables. Primitive types include:

  • Integers: Signed (i8i16i32i64i128) and unsigned (u8u16u32u64u128). The number indicates the bit size and memory consumed.
  • Floating-Point: f32 and f64 for decimal numbers.
  • Boolean: bool values are true or false.
  • Character: char represents a single Unicode scalar value.

Example:

let x: i32 = 42;       // signed 32-bit integer
let y: u64 = 100;      // unsigned 64-bit integer
let pi: f64 = 3.14;    // 64-bit float
let is_snowing: bool = true;
let letter: char = 'A';

Rust enforces strict type safety; for example, assigning negative values to unsigned integers causes compile-time errors.

Compound Data Types

Rust supports grouping multiple values:

  • Arrays: Fixed-size, homogeneous collections.
let numbers: [i32; 5] = [1, 2, 3, 4, 5];
  • Tuples: Fixed-size, heterogeneous collections.
let human: (&str, i32, bool) = ("Alice", 30, false);
  • Slices: Dynamically-sized views into arrays or strings, represented as references with &.
  • Strings: Two main types in Rust:
    • String slice (&str): Immutable reference to a string literal stored in binary or elsewhere.
    • String (String): Growable, mutable, heap-allocated string type.

Example of mutable strings:

let mut s = String::from("Hello");
s.push_str(" World");

Functions in Rust

Functions are declared with the fn keyword, follow snake_case naming, and can accept parameters and return values.

Example:

fn main() {
    hello_world();
    tell_height(182);
}

fn hello_world() {
    println!("Hello, Rust!");
}

fn tell_height(height: i32) {
    println!("My height is {} cm", height);
}
  • Return values: Functions return values via expressions without semicolons.
fn add(a: i32, b: i32) -> i32 {
    a + b  // returns the sum
}
  • Expressions vs Statements: Expressions return values; statements do not.

Ownership, Borrowing, and References

Understanding Ownership

Rust’s ownership system manages memory without a garbage collector. The rules are:

  1. Each value has a single owner.
  2. Only one owner at a time.
  3. When the owner goes out of scope, the value is dropped.

Example:

let s1 = String::from("rust");
let s2 = s1;  // ownership moved to s2; s1 is no longer valid

Borrowing and References

You can borrow values without taking ownership by using references:

  • Immutable references: Multiple allowed; read-only access.
let s = String::from("hello");
let len = calculate_length(&s);

fn calculate_length(s: &String) -> usize {
    s.len()
}
  • Mutable references: Only one allowed; allows modifying the borrowed value.
let mut x = 5;
let r = &mut x;
*r += 1;

Rust enforces rules at compile time to prevent data races or dangling pointers.

Variables, Mutability, and Shadowing

  • Variables are immutable by default. To mutate, use mut:
let mut a = 5;
a = 10;  // allowed because of mut
  • Constants: Declared with const, always immutable, must have type annotation, and can be declared in global scope:
const PI: f64 = 3.14;
  • Shadowing: Allows redeclaring a variable with the same name, optionally changing its type or value.
let x = 5;
let x = x + 1;  // shadows previous x

Shadowing differs from mutability as it creates a new binding.

Control Flow in Rust

If Expressions

Control flow based on conditionals:

let age = 18;
if age >= 18 {
    println!("You can drive");
} else {
    println!("You cannot drive");
}

Supports else if chains and conditional assignment:

let number = if condition { 5 } else { 6 };

Loops

Rust offers:

  • loop: Infinite loop until break.
loop {
    println!("Hello");
    break;
}
  • while: Loop while a condition is true.
while number != 0 {
    println!("{}", number);
    number -= 1;
}
  • for: Loop over collections.
for i in 1..5 {
    println!("{}", i);
}
  • Loop labels: Used in nested loops for clarity with break and continue.

Structs and Enums

Structs

Custom data types grouping related fields, with named fields:

struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

let mut user1 = User {
    active: true,
    username: String::from("user123"),
    email: String::from("user@example.com"),
    sign_in_count: 1,
};

user1.email = String::from("new_email@example.com");
  • Tuple structs: Like tuples with named types but unnamed fields.
  • Unit-like structs: Empty structs useful for traits.

Enums

Enums define types that can be one of several variants, optionally storing data:

enum IpAddrKind {
    V4,
    V6,
}

let four = IpAddrKind::V4;
let six = IpAddrKind::V6;

Variants can hold data:

enum IpAddr {
    V4(String),
    V6(String),
}

let home = IpAddr::V4(String::from("127.0.0.1"));

Enhanced enums allow more complex data representation.


Error Handling in Rust

Rust encourages explicit error handling through:

Option

Used when a value might be present or absent, avoiding null references:

fn divide(numerator: f64, denominator: f64) -> Option<f64> {
    if denominator == 0.0 {
        None
    } else {
        Some(numerator / denominator)
    }
}

Result<T, E>

Used for recoverable errors with detailed error information:

fn divide(numerator: f64, denominator: f64) -> Result&lt;f64, String> {
    if denominator == 0.0 {
        Err(String::from("Cannot divide by zero"))
    } else {
        Ok(numerator / denominator)
    }
}

Use match to handle returned Option or Result.


Common Collections in Rust

Vectors

Growable arrays storing homogeneous data:

let mut v: Vec&lt;i32> = Vec::new();
v.push(1);
v.push(2);

Access elements by indexing or the get method, which returns an Option.

UTF-8 Strings

Rust strings are UTF-8 encoded, allowing multilingual text:

let mut s = String::from("Hello");
s.push('!');
s.push_str(" World");

HashMaps

Key-value stores similar to dictionaries in other languages:

use std::collections::HashMap;

let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

for (key, value) in &amp;scores {
    println!("{}: {}", key, value);
}

Rust uses secure hashing algorithms to protect against denial-of-service attacks.


Conclusion

This comprehensive Rust course has covered fundamental topics crucial for beginners to start programming effectively:

  • Installation and setup
  • Data types: primitive and compound
  • Functions and control flow
  • Ownership, borrowing, and references for memory safety
  • Variables, mutability, and shadowing
  • Structs and enums for custom data types
  • Error handling with Option and Result
  • Collections: vectors, strings, and hashmaps

Rust offers the power of low-level programming with the safety and productivity of modern languages. With its growing popularity and industry adoption, mastering Rust opens doors to creating fast, reliable, and concurrent applications.

Keep practicing these concepts, explore Rust’s official documentation, and build projects to deepen your understanding. Happy coding with Rust!

Common error

That error is a classic Windows‑MSVC toolchain issue: Rust is trying to link your program using link.exe, but it can’t find msvcrt.lib — the Microsoft C Runtime library.

On Windows, Rust requires the MSVC build tools (even if you don’t use Visual Studio itself). When this library is missing, it usually means one of three things:

Why this happens

1. The MSVC toolchain is installed incorrectly or incompletely

Rust expects to find:

C:\Program Files\Microsoft Visual Studio\&lt;version>\Community\VC\Tools\MSVC\&lt;version>\lib\x64\msvcrt.lib

Your error shows:

LINK : fatal error LNK1104: cannot open file 'msvcrt.lib'

This means the file is missing or the installation is corrupted.

2. You installed Visual Studio but not the “Desktop development with C++” workload

This workload contains the MSVC linker, Windows SDK, and the CRT libraries.

3. You installed Visual Studio 2022 Preview or Build Tools only

Rust sometimes fails to detect incomplete installations.

How to fix it (the reliable way)

Open Visual Studio Installer → Modify your installation → ensure these are checked:

✔ Desktop development with C++

Inside it, make sure these components are selected:

  • MSVC v143 or v142 build tools
  • Windows 10/11 SDK
  • C++ CMake tools
  • C++ ATL/MFC (optional)
  • C++ core features

This guarantees msvcrt.lib is installed.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.